/* eslint-disable */
function gltSubtractVectors(v3First, v3Second, v3Result)//v3Result = v3First - v3Second
{
    v3Result || (v3Result = []);
    for(var i=0; i<3; ++i) v3Result[i] = v3First[i] - v3Second[i];
    return v3Result;
}
function gltVectorCrossProduct(v3U, v3V, v3Result)//v3Result = v3U X v3V
{
    v3Result || (v3Result = []);
    v3Result[0] = v3U[1]*v3V[2] - v3V[1]*v3U[2];
    v3Result[1] = -v3U[0]*v3V[2] + v3V[0]*v3U[2];
    v3Result[2] = v3U[0]*v3V[1] - v3V[0]*v3U[1];
    return v3Result;
}
function gltVectorDotProductV(v, vvU, vvV)//返回v维向量的点积 vvU . vvV
{
    var dot = 0;
    for(var i=0; i<v; ++i) dot += vvU[i] * vvV[i];
    return dot;
}
function gltScaleVector(v3Vector, fScale, v3Result)//v3Result = v3Vector * fScale
{ 
    v3Result || (v3Result = v3Vector);
    for(var i=0; i<3; ++i) v3Result[i] = v3Vector[i] * fScale;
    return v3Result;
}
function gltGetVectorLengthSqrd(v3Vector)//返回模长的平方
{ 
    return (v3Vector[0]*v3Vector[0]) + (v3Vector[1]*v3Vector[1]) + (v3Vector[2]*v3Vector[2]);
}
function gltGetVectorLength(v3Vector)//返回模长
{ 
    return Math.sqrt(gltGetVectorLengthSqrd(v3Vector)); 
}
function gltNormalizeVector(v3Normal)
{ 
    var fLength = 1.0 / gltGetVectorLength(v3Normal);
    return gltScaleVector(v3Normal, fLength); 
}
function gltGetNormalVector(v3P1, v3P2, v3P3, v3Normal)//计算CCW的三个点决定的平面的法线
{
    var v3V1 = [];
    var v3V2 = [];
    
    gltSubtractVectors(v3P2, v3P1, v3V1);
    gltSubtractVectors(v3P3, v3P1, v3V2);
    
    gltVectorCrossProduct(v3V1, v3V2, v3Normal);
    return gltNormalizeVector(v3Normal);
}
function gltGetPlaneEquation(v3Point1, v3Point2, v3Point3, v4Plane)//计算CCW的三个点决定的平面的平面方程的系数
{
    v4Plane || (v4Plane = []);
    gltGetNormalVector(v3Point1, v3Point2, v3Point3, v4Plane);    
    v4Plane[3] = -(v4Plane[0] * v3Point3[0] + v4Plane[1] * v3Point3[1] + v4Plane[2] * v3Point3[2]);
    return v4Plane;
}
export function gltMakeShadowMatrix(v3Points3, v4LightPos, destMat4)
//v3Points3：三个v3元素的数组；是平面上CCW的三个点
//v4LightPos：光源位置
//destMat4：保存计算出的阴影矩阵，可选
{
    var v4PlaneEquation = gltGetPlaneEquation(v3Points3[0], v3Points3[1], v3Points3[2]);
    var dot = gltVectorDotProductV(4, v4PlaneEquation, v4LightPos);

    destMat4 || (destMat4 = []);
 
    // First column
    destMat4[0] = dot - v4LightPos[0] * v4PlaneEquation[0];
    destMat4[4] = 0.0 - v4LightPos[0] * v4PlaneEquation[1];
    destMat4[8] = 0.0 - v4LightPos[0] * v4PlaneEquation[2];
    destMat4[12] = 0.0 - v4LightPos[0] * v4PlaneEquation[3];

    // Second column
    destMat4[1] = 0.0 - v4LightPos[1] * v4PlaneEquation[0];
    destMat4[5] = dot - v4LightPos[1] * v4PlaneEquation[1];
    destMat4[9] = 0.0 - v4LightPos[1] * v4PlaneEquation[2];
    destMat4[13] = 0.0 - v4LightPos[1] * v4PlaneEquation[3];

    // Third Column
    destMat4[2] = 0.0 - v4LightPos[2] * v4PlaneEquation[0];
    destMat4[6] = 0.0 - v4LightPos[2] * v4PlaneEquation[1];
    destMat4[10] = dot - v4LightPos[2] * v4PlaneEquation[2];
    destMat4[14] = 0.0 - v4LightPos[2] * v4PlaneEquation[3];

    // Fourth Column
    destMat4[3] = 0.0 - v4LightPos[3] * v4PlaneEquation[0];
    destMat4[7] = 0.0 - v4LightPos[3] * v4PlaneEquation[1];
    destMat4[11] = 0.0 - v4LightPos[3] * v4PlaneEquation[2];
    destMat4[15] = dot - v4LightPos[3] * v4PlaneEquation[3];

    return destMat4;
}